package com.xxx.yuedong.community.service.impl;

import com.xxx.yuedong.common.exception.YuedongException;
import com.xxx.yuedong.common.pojo.PageData;
import com.xxx.yuedong.community.controller.form.DynamicLikeForm;
import com.xxx.yuedong.community.db.cache.RedisCache;
import com.xxx.yuedong.community.db.dao.DynamicLikeDao;
import com.xxx.yuedong.community.pojo.*;
import com.xxx.yuedong.community.service.DynamicLikeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 点赞业务层
 * 之后合并到DynamicServiceImpl中
 *
 * @Author YinXi
 * @Versin 1.0.0
 * @Date 2023/8/7
 */
@Slf4j
@Service
public class DynamicLikeServiceImpl implements DynamicLikeService {
    @Autowired
    private DynamicLikeDao dynamicLikeDao;
    @Autowired
    private RedisCache dynamicLikeCache;
    @Value("${yuedong.dynamic.default-query-page-size}")
    private Integer defaultQueryPageSize;


    /**
     * 点赞
     */
    @Override
    public void getDynamicLike(DynamicLikeForm form) {
//      判断是否存在该动态id
        Dynamic dynamic = dynamicLikeDao.selectByDynamicId(form.getDynamicId());
        if(dynamic == null){
            log.error("异常消息用户id{}：【未查到要点赞的动态】",form.getUserId());
            throw new YuedongException(HttpStatus.SC_NO_CONTENT,"无此动态");
        }
//        判断该用户是否点赞过该动态
        List<DynamicLikeForm> dynamicLikeForms = dynamicLikeCache.list(RedisCache.KEY_DYNAMICLIKE);
        DynamicLike dynamicLike = dynamicLikeDao.selectDynamicLikeForm(form);
        if(dynamicLikeForms.contains(form)||dynamicLike != null){
            log.warn("异常消息用户id{}：【重复点赞相同动态】",form.getUserId());
            throw new YuedongException(HttpStatus.SC_ACCEPTED,"已经点赞过该动态");
        }
//        将点赞的数据插入到Redis缓存当中
        Long num = dynamicLikeCache.insert(form, RedisCache.KEY_DYNAMICLIKE);
        if(num<=0){
            log.error("异常消息用户id{}：【Redis数据库异常无法新增数据】",form.getUserId());
            throw new YuedongException(HttpStatus.SC_BAD_REQUEST,"系统繁忙请稍好尝试……");
        }
    }

    /**
     * 取消点赞
     */
    @Override
    public void outDynamicLike(DynamicLikeForm form) {
//        判断是否存在该动态id
        Dynamic dynamic = dynamicLikeDao.selectByDynamicId(form.getDynamicId());
        if(dynamic == null){
            log.error("异常消息用户id{}：【未查到要点赞的动态】",form.getUserId());
            throw new YuedongException(HttpStatus.SC_NO_CONTENT,"无此动态");
        }
//        判断该用户id是否点赞过该动态
        List<DynamicLikeForm> dynamicLikeForms = dynamicLikeCache.list(RedisCache.KEY_OUTDYNAMICLIKE);
        if(dynamicLikeDao.selectDynamicLikeForm(form) == null||dynamicLikeForms.contains(form)){
            log.warn("异常消息用户id{}：【用户未点赞过该条动态】",form.getUserId());
            throw new YuedongException(HttpStatus.SC_NO_CONTENT,"未点赞过该动态");
        }
        Long num = dynamicLikeCache.insert(form, RedisCache.KEY_OUTDYNAMICLIKE);
        if(num<=0){
            log.error("异常消息用户id{}：【Redis数据库异常无法新增数据】",form.getUserId());
            throw new YuedongException(HttpStatus.SC_BAD_REQUEST,"系统繁忙请稍好尝试……");
        }
    }

    /**
     * 获取某一条动态的点赞数
     * - 判断是否存在该动态id
     */
    @Override
    public int countDynamicLike(Long dynamicId) {
//        判断是否存在该动态id
        Dynamic dynamic = dynamicLikeDao.selectByDynamicId(dynamicId);
        if(dynamic == null){
            log.error("异常动态id{}：【未查找到该动态】",dynamicId);
            throw new YuedongException(HttpStatus.SC_NO_CONTENT,"无此动态");
        }
        Integer num = dynamicLikeDao.countByDynamicId(dynamicId);
        if(num == null){
            return 0;
        }else {
            return num;
        }
    }

    /**
     * 获取某一条动态的前四位点赞者
     */
    @Override
    public List<LikeUser> getDynamicLiker(Long dynamicId) {
//        判断是否存在该动态id
        Dynamic dynamic = dynamicLikeDao.selectByDynamicId(dynamicId);
        if(dynamic == null){
            log.error("异常动态id{}：【未查找到该动态】",dynamicId);
            throw new YuedongException(HttpStatus.SC_NO_CONTENT,"无此动态");
        }
        return new ArrayList<>(dynamicLikeDao.selectAllByDynamicId(dynamicId));
    }

    /**
     * 判断当前用户是否点赞过当前动态
     */
    @Override
    public DynamicLike isDynamicLiker(Long dynamicId,Long userId) {
        DynamicLikeForm dynamicLikeForm = new DynamicLikeForm();
        dynamicLikeForm.setDynamicId(dynamicId);
        dynamicLikeForm.setUserId(userId);
        return dynamicLikeDao.selectDynamicLikeForm(dynamicLikeForm);
    }

    /**
     * 获取用户的喜欢列表
     */
    @Override
    public List<Dynamic> dynamicLists(Long userId) {
        return dynamicLikeDao.selectDynamicLikeByUserId(userId);
    }

    /**
     * 重建动态点赞缓存列表
     */
    @Override
    public void rebulidDynamicLikeCache() {
        List<DynamicLikeForm> dynamicLike = dynamicLikeCache.list(RedisCache.KEY_DYNAMICLIKE);
        List<DynamicLikeForm> dynamicOutLike = dynamicLikeCache.list(RedisCache.KEY_OUTDYNAMICLIKE);
        if (!dynamicLike.isEmpty()){
            int num = dynamicLikeDao.insertDynamicLike(dynamicLike);
            if (num<=0){
                log.error("【MySQL数据库异常无法新增数据】");
                throw new YuedongException(HttpStatus.SC_BAD_REQUEST,"系统繁忙请稍好尝试……");
            }
        }
        if(!dynamicOutLike.isEmpty()){
            int num = dynamicLikeDao.deleteDynamicLike(dynamicOutLike);
            if (num<=0){
                log.error("【MySQL数据库异常无法新增数据】");
                throw new YuedongException(HttpStatus.SC_BAD_REQUEST,"系统繁忙请稍好尝试……");
            }
        }
        dynamicLikeCache.deleteList(RedisCache.KEY_DYNAMICLIKE);
        dynamicLikeCache.deleteList(RedisCache.KEY_OUTDYNAMICLIKE);
    }

    /**
     * 判断是否在Redis中存在用户的喜欢列表
     */
    @Override
    public boolean isDynamicLikeList(Long userId) {
        return dynamicLikeCache.isKey("dynamic:like:list:"+userId);
    }


    /**
     * 加载用户的喜欢列表
     */
    @Override
    public void buildDynamicLikeList(Long userId) {
        dynamicLikeCache.deleteList("dynamic:like:list:"+userId);
        dynamicLikeCache.save(dynamicLikeDao.selectDynamicLikeByUserId(userId),"dynamic:like:list:"+userId);
    }
    /**
     * 分页加载用户的喜欢列表
     */
    @Override
    public PageData<Dynamic> list(Integer pageNum, Long userId) {
        PageData<Dynamic> pageData = dynamicLikeCache.pageList(pageNum,defaultQueryPageSize,"dynamic:like:list:"+userId);
        return pageData;
    }

    /**
     * 获取当前Redis缓存中的喜欢列表的key
     */
    @Override
    public Set<String> getDynamicLikeKeys(String pattern) {
        return dynamicLikeCache.getKeys(pattern);
    }

    /**
     * 重构喜欢列表的缓存
     */
    @Override
    public void rebulidDynamicCache(Set<String> list) {
        for (String key:list){
            dynamicLikeCache.deleteList(key);
        }
    }
}
